#include "ReferenceSequence.h"

#include <string>
#include <cerrno>
#include <cstddef>

#include <iostream>

using namespace std;

const int ReferenceSequence::BUFFER_SIZE = 4096;

ReferenceSequence::ReferenceSequence(ifstream &in, ulong maxStrLen) :
		strLen(maxStrLen)
{;
	bitsets = new DynamicBitset*[CHAR_NUM];
	for (int i = 0; i < CHAR_NUM; i++)
		bitsets[i] = new DynamicBitset(strLen);
	
	char block[BUFFER_SIZE];
	size_t bitsetIndex = 0;
	bool nameRead = false;
	while (!in.eof())
	{
		in.read(&block[0], BUFFER_SIZE);
		streamsize bytesRead = in.gcount();
		for (int i = 0; i < bytesRead; i++)
		{
			/* Just read the sequence name until the first new-line */
			if (!nameRead)
			{
				if (block[i] == '\n')
					nameRead = true;
			}
			else
			{
				/* enter the data to the bitsets */
				switch (block[i])
				{
				case 'A':
					bitsets[A]->set(bitsetIndex++);
					break;
				case 'C':
					bitsets[C]->set(bitsetIndex++);
					break;
				case 'G':
					bitsets[G]->set(bitsetIndex++);
					break;
				case 'T':
					bitsets[T]->set(bitsetIndex++);
					break;
				default:
					/* Do nothing */
					break;
				}
			}
		}

	}

}

ReferenceSequence::~ReferenceSequence()
{
}

int ReferenceSequence::getBit(short c, size_t indx) const
{
	if (c < CHAR_NUM)
		return bitsets[c]->test(indx);
	return 0;
}

#ifdef DEBUG
#include <iostream>

using namespace std;

void ReferenceSequence::print() const
{
	cout << "bitsetA: " << endl;
	bitsets[A]->printBitset();
	cout << "bitsetC: " << endl;
	bitsets[C]->printBitset();
	cout << "bitsetG: " << endl;
	bitsets[G]->printBitset();
	cout << "bitsetT: " << endl;
	bitsets[T]->printBitset();
}
#endif /* DEBUG */

